﻿using AutoMapper;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using Microsoft.EntityFrameworkCore;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;

namespace DFGK_WMS.Repository
{
    public class TInventoryRepository : BaseRepository<TInventory>, ITInventoryRepository
    {
        public TInventoryRepository(DFGK_DB context, IMapper mapper) : base(context, mapper)
        {
        }

        public List<TInventoryDto> GetTInventoryDtoPage(out int totalCount, int? owerId, int? whId, string? wlName, int? kcState, int pageIndex = 1, int pageSize = 10)
        {
            var list = Context.TInventories.AsNoTracking();
            if (owerId.HasValue)
            {
                list = list.Where(s => s.OwnerId == owerId);
            }
            if (whId.HasValue)
            {
                list = list.Where(s => s.WarehouseId == whId);
            }
            if (!string.IsNullOrEmpty(wlName))
            {
                list = list.Where(s => s.MaterialName.Contains(wlName));
            }
            if (kcState.HasValue)
            {
                list = list.Where(s=>s.Status==kcState);
            }
            totalCount = list.Count();
            // 分页处理
            var paginatedList = list.OrderByDescending(s => s.CreateDate)
                                    .Skip((pageIndex - 1) * pageSize)
                                    .Take(pageSize)
                                    .AsNoTracking()
                                    .ToList()
                                    .Select(s => new TInventoryDto()
                                    {
                                        Id = s.Id,
                                        PalletBarcode = s.PalletBarcode,
                                        LocationName = s.LocationName,
                                        MaterialName = s.MaterialName,
                                        AvailableQty = (int)s.AvailableQty.GetValueOrDefault(),
                                        StatusVal = GetInventoryStatus(s.Status),
                                        MaterialCode = s.MaterialCode,
                                        BatchNo = s.BatchNo,
                                        SmallBatchNo = s.SmallBatchNo,
                                        LocationCode = s.LocationCode,
                                        ErplocationCode = s.ErplocationCode,
                                        OwnerName = s.OwnerName,
                                        AreaName = s.AreaName,
                                        SupplierName = s.SupplierName,
                                        ExpireDate = s.ExpireDate,
                                        ProductDate = s.ProductDate,
                                        TotalWeight=s.TotalWeight,
                                        IsWarning= IsWarning(s),
                                        WhetherQualified=s.WhetherQualified
                                        //InventoryDetailDtos = GetInventoryDetailDtos(s.Id)
                                    })
                                    .ToList();
            return paginatedList;
        }
        private bool IsWarning(TInventory inventory)
        {
            var mater = Context.TMaterial.FirstOrDefault(s=>s.Code==inventory.MaterialCode);
            if (mater == null)
            {
                return false;
            }
            var timeInt = Convert.ToInt32(DateTime.Now.ToString("yyyyMMdd"));
            //如果当前日期减去小批次号的日期等于或者大于物料预警天数则开启物料预警
            if (timeInt - ExtractDateFromCode(inventory.SmallBatchNo) >= mater.WarningDays.GetValueOrDefault())
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 小批次号拆解
        /// </summary>
        /// <param name="bacNo">小批次号</param>
        /// <returns></returns>
        private int ExtractDateFromCode(string bacNo)
        {
            if (string.IsNullOrEmpty(bacNo))
            {
                return 0;
            }
            if (bacNo.Length < 12)
            {
                return 0;
            }
            string time = bacNo.Substring(2, 8);
            bool containsLetter = time.Any(char.IsLetter);
            if (containsLetter)
            {
                return 0;
            }
            return Convert.ToInt32(time);
        }
        public string GetInventoryStatus(int? status)
        {
            string inventoryStatus;

            switch (status)
            {
                case 1:
                    inventoryStatus = "正常库存";
                    break;
                case 2:
                    inventoryStatus = "转移中的库存";
                    break;
                case 3:
                    inventoryStatus = "入库在途";
                    break;
                case 4:
                    inventoryStatus = "出库在途";
                    break;
                case 5:
                    inventoryStatus = "限制使用的库存";
                    break;
                case 6:
                    inventoryStatus = "异常库存";
                    break;
                case 7:
                    inventoryStatus = "预分配库存";
                    break;
                case 8:
                    inventoryStatus = "冻结库存";
                    break;
                default:
                    inventoryStatus = "无";
                    break;
            }

            return inventoryStatus;
        }

        private List<InventoryDetailDto>? GetInventoryDetailDtos(int kqId)
        {
            return Context.TInventoryDetails.AsNoTracking().Where(s => s.InventoryId == kqId).Select(s=>new InventoryDetailDto()
            {
                PackageBarcode=s.PackageBarcode,
                Barcode=s.Barcode,
                SkuNum=s.SkuNum,
            }).ToList();
        }

        public List<TInventory> GetTInventoryPage(out int totalCount, out int totalQty, out decimal totalTotalWeight, int? owerId, int? whId, string? wlName, int pageIndex = 1, int pageSize = 10)
        {
            var list = Context.TInventories.AsQueryable();

            if (owerId.HasValue)
            {
                list = list.Where(s => s.OwnerId == owerId);
            }
            if (whId.HasValue)
            {
                list = list.Where(s => s.WarehouseId == whId);
            }
            if (!string.IsNullOrEmpty(wlName))
            {
                list = list.Where(s => s.MaterialName.Contains(wlName));
            }
            
            var res = list.OrderBy(x => x.CreateDate)
                        .AsNoTracking()
                        .ToList()
                        .AsEnumerable()
                        .GroupBy(s => s.MaterialId)
                        .Select(g => new TInventory()
                        {
                            Id = g.First().Id,
                            MaterialCode = g.First().MaterialCode,
                            MaterialName = g.First().MaterialName,
                            OwnerName = g.First().OwnerName,
                            AvailableQty = (int)g.Sum(s => s.AvailableQty).GetValueOrDefault(),
                            CreateDate = g.First().CreateDate,
                            TotalWeight = g.First().TotalWeight,
                            //TotalWeight = g.First().AvailableQty * GetMaterialTonnagefactor(g.First()),
                        })
                        .OrderByDescending(x => x.CreateDate)
                        .ToList();

            totalCount = res.Count();
            totalQty = (int)res.Sum(s => s.AvailableQty).GetValueOrDefault();
            totalTotalWeight = res.Sum(s => s.TotalWeight).GetValueOrDefault();
            // 分页处理
            var paginatedList = res.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return paginatedList.ToList();
        }
        //private decimal GetMaterialTonnagefactor(TInventory inv)
        //{
        //    var res = Context.TMaterial.AsNoTracking().FirstOrDefault(s => s.Code == inv.MaterialCode);
        //    if (res == null)
        //    {
        //        return 0;
        //    }
        //    return res.Tonnagefactor;
        //}

        /// <summary>
        /// 查询所有库存表信息（非分页）
        /// </summary>
        /// <returns></returns>
        public List<TInventory> GetInventoryList()
        {
            var list = Context.TInventories.AsNoTracking();
            return list.OrderBy(r => r.Id).ToList();
        }
        /// <summary>
        /// 导出库存
        /// </summary>
        /// <returns></returns>
        public List<TInventory> GetTInventoryExcel(int? owerId, int? whId, string? wlName)
        {
            var list = Context.TInventories.AsQueryable();

            if (owerId.HasValue)
            {
                list = list.Where(s => s.OwnerId == owerId);
            }
            if (whId.HasValue)
            {
                list = list.Where(s => s.WarehouseId == whId);
            }
            if (!string.IsNullOrEmpty(wlName))
            {
                list = list.Where(s => s.MaterialName.Contains(wlName));
            }

            var res = list
                .OrderBy(x => x.CreateDate)
                        .GroupBy(s => s.MaterialId)
                        .Select(g => new TInventory()
                        {
                            Id = g.First().Id,
                            MaterialCode = g.First().MaterialCode,
                            MaterialName = g.First().MaterialName,
                            OwnerName = g.First().OwnerName,
                            TotalPrice = g.First().TotalPrice,
                            AvailableQty = g.Sum(s => s.AvailableQty),
                            CreateDate = g.First().CreateDate,
                        })
                        .OrderByDescending(x => x.CreateDate)
                        .ToList();

            return res.ToList(); ;
        }

        /// <summary>
        /// 批次汇总查询
        /// </summary>
        /// <param name="totalCount"></param>
        /// <param name="owerId"></param>
        /// <param name="whId"></param>
        /// <param name="wlName"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public List<TInventory> GetTInventoryBatchNo(out int totalCount, out int totalQty,out decimal totalTotalWeight, int? owerId, int? whId, string? wlName, int pageIndex = 1, int pageSize = 10)
        {
            var list = Context.TInventories.AsQueryable();
            //先留着货主
            if (owerId.HasValue)
            {
                list = list.Where(s => s.OwnerId == owerId);
            }
            if (whId.HasValue)
            {
                list = list.Where(s => s.WarehouseId == whId);
            }
            if (!string.IsNullOrEmpty(wlName))
            {
                list = list.Where(s => s.MaterialName.Contains(wlName));
            }

            var res = list.OrderBy(x => x.CreateDate)
                        .AsNoTracking()
                        .ToList()
                        .AsEnumerable()
                        .GroupBy(s => s.BatchNo)
                        .Select(g => new TInventory()
                        {
                            Id = g.First().Id,
                            MaterialCode = g.First().MaterialCode,
                            MaterialName = g.First().MaterialName,
                            BatchNo = g.First().BatchNo,
                            AvailableQty = (int)g.Sum(s => s.AvailableQty).GetValueOrDefault(),
                            CreateDate = g.First().CreateDate,
                            //TotalWeight = g.First().AvailableQty * GetMaterialTonnagefactor(g.First()),
                        })
                        .OrderByDescending(x => x.CreateDate)
                        .ToList();

            totalCount = res.Count();
            totalQty = (int)res.Sum(s=>s.AvailableQty).GetValueOrDefault();
            totalTotalWeight = res.Sum(s=>s.TotalWeight).GetValueOrDefault();
            // 分页处理
            var paginatedList = res.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return paginatedList.ToList(); ;
        }

        /// <summary>
        /// 获取库存信息
        /// </summary>
        /// <param name="totalCount"></param>
        /// <param name="wlName"></param>
        /// <param name="whId"></param>
        /// <param name="owerId"></param>
        /// <param name="wlCode"></param>
        /// <param name="batchNo"></param>
        /// <param name="materialType"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public List<InventoryAllDto> GetAllInventory(out int totalCount,string? wlName, int? whId, int? owerId, string? wlCode, string? batchNo, int? materialType, int pageIndex, int pageSize)
        {
            var list = Context.TInventories.AsNoTracking();
            if (owerId.HasValue)
            {
                list = list.Where(s => s.OwnerId == owerId);
            }
            if (whId.HasValue)
            {
                list = list.Where(s => s.WarehouseId == whId);
            }
            if (!string.IsNullOrEmpty(wlName))
            {
                list = list.Where(s => s.MaterialName.Contains(wlName));
            }
            if(wlCode != null)
            {
                list = list.Where( x=> x.MaterialCode.Contains(wlCode));
            }
            if (batchNo != null)
            {
                list = list.Where(x => x.BatchNo == batchNo);
            }
            if (materialType != null)
            {
                if(materialType == 1)
                {
                    list = list.Where(x => x.WarehouseCode == "A01");
                }else if(materialType == 2)
                {
                    list = list.Where(x => x.WarehouseCode == "A04");
                }
            }
            totalCount = list.Count();
            // 分页处理
            var paginatedList = list.OrderByDescending(s => s.CreateDate)
                                    .Skip((pageIndex - 1) * pageSize)
                                    .Take(pageSize)
                                    .AsNoTracking()
                                    .ToList()
                                    .Select(s => new InventoryAllDto()
                                    {
                                        Id = s.Id,
                                        PalletBarcode = s.PalletBarcode,
                                        LocationName = s.LocationName,
                                        MaterialName = s.MaterialName,
                                        AvailableQty = (int)s.AvailableQty.GetValueOrDefault(),
                                        StatusVal = GetInventoryStatus(s.Status),
                                        MaterialCode = s.MaterialCode,
                                        BatchNo = s.BatchNo,
                                        LocationCode = s.LocationCode,
                                        OwnerName = s.OwnerName,
                                        AreaName = s.AreaName,
                                        SupplierName = s.SupplierName,
                                        TotalWeight = s.TotalWeight,
                                        WeightUnitName = s.WeightUnitName,
                                        NumUnitName = s.NumUnitName,
                                        ModelSpec = s.ModelSpec,
                                        //InventoryDetailDtos = GetInventoryDetailDtos(s.Id)
                                    })
                                    .ToList();
            return paginatedList.ToList();
        }
    }
}
